#ifndef _NODE_H_
#define _NODE_H_

////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////

#include "Arc.hpp"

////////////////////////////////////////////////////////////////////////////////
// Namespaces
////////////////////////////////////////////////////////////////////////////////

namespace Types {

////////////////////////////////////////////////////////////////////////////////
// Implementation
////////////////////////////////////////////////////////////////////////////////

/**
 *  Generic Node
 */
template <typename TN = int, typename TA = int>
class Node {

	public:

		/// Constructor
		Node() {}

		/// Constructor
		Node(const TN & data)
		:	data(data)
		{}

		/// Creates a copy of the given instance
		Node(const Node<TN,TA> & inst)
		:	data(inst.data),
			arcs(inst.arcs)
		{}
		
		/// Affectation operator
		Node & operator = (const Node<TN,TA> & inst) {
			if (this != &inst) {
				this->data = inst.data;
				this->arcs = inst.arcs;
			}
			return *this;
		}

		/// Returns the data (read only)
		const TN & GetData() const { return this->data; }

		/// Returns the data
		TN & Data() { return this->data; }
		
		/// Returns the number of arcs
		const unsigned int GetNbArcs() const { return this->arcs.size(); }

		/// Returns the required arc (read only)
		const Types::Arc<TA> & GetArc(const unsigned int i) const { return this->arcs[i]; }

		/// Returns the required arc
		Types::Arc<TA> & Arc(const unsigned int i) { return this->arcs[i]; }

		/// Adds an arc
		void AddArc(const Types::Arc<TA> & arc) { this->arcs.push_back(arc); }

		/// Removes the given arc
		void RemoveArc(const unsigned int pos) { this->arcs.erase(this->arcs.begin()+pos); }

		/// Clear the node of all its arcs
		void Clear() { this->arcs.clear(); }
		
	protected:

		/// Node data
		TN data;

		/// Arcs starting from the current node
		std::vector< Types::Arc<TA> > arcs;

};

////////////////////////////////////////////////////////////////////////////////
// Closing Namespaces
////////////////////////////////////////////////////////////////////////////////

}

////////////////////////////////////////////////////////////////////////////////

#endif
